home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / k051649.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  5KB  |  188 lines

  1. /***************************************************************************
  2.  
  3.     Konami 051649 - SCC1 sound as used in Haunted Castle, City Bomber
  4.  
  5.     This file is pieced together by Bryan McPhail from a combination of
  6.     Namco Sound, Amuse by Cab, Haunted Castle schematics and whoever first
  7.     figured out SCC!
  8.  
  9.     The 051649 is a 5 channel sound generator, each channel gets it's
  10.     waveform from RAM (32 bytes per waveform, 8 bit signed data).
  11.  
  12.     Frequency information for each channel appears to be 10 bits.
  13.  
  14. ***************************************************************************/
  15.  
  16. #include "driver.h"
  17.  
  18. #define FREQBASEBITS    16
  19.  
  20. /* this structure defines the parameters for a channel */
  21. typedef struct
  22. {
  23.     unsigned long counter;
  24.     int frequency;
  25.     int volume;
  26.     int key;
  27.     /*unsigned char waveform[32];*/
  28.     signed char waveform[32];        /* 19991207.CAB */
  29. } k051649_sound_channel;
  30.  
  31. static k051649_sound_channel channel_list[5];
  32.  
  33. /* global sound parameters */
  34. static int stream,mclock,rate;
  35.  
  36. /* mixer tables and internal buffers */
  37. static INT16 *mixer_table;
  38. static INT16 *mixer_lookup;
  39. static short *mixer_buffer;
  40.  
  41. /* build a table to divide by the number of voices */
  42. static int make_mixer_table(int voices)
  43. {
  44.     int count = voices * 256;
  45.     int i;
  46.     int gain = 8;
  47.  
  48.     /* allocate memory */
  49.     mixer_table = malloc(512 * voices * sizeof(INT16));
  50.     if (!mixer_table)
  51.         return 1;
  52.  
  53.     /* find the middle of the table */
  54.     mixer_lookup = mixer_table + (256 * voices);
  55.  
  56.     /* fill in the table - 16 bit case */
  57.     for (i = 0; i < count; i++)
  58.     {
  59.         int val = i * gain * 16 / voices;
  60.         if (val > 32767) val = 32767;
  61.         mixer_lookup[ i] = val;
  62.         mixer_lookup[-i] = -val;
  63.     }
  64.  
  65.     return 0;
  66. }
  67.  
  68.  
  69. /* generate sound to the mix buffer */
  70. static void K051649_update(int ch, INT16 *buffer, int length)
  71. {
  72.     k051649_sound_channel *voice=channel_list;
  73.     short *mix;
  74.     int i,v,f,j,k;
  75.  
  76.     /* zap the contents of the mixer buffer */
  77.     memset(mixer_buffer, 0, length * sizeof(short));
  78.  
  79.     for (j=0; j<5; j++) {
  80.         v=voice[j].volume;
  81.         f=voice[j].frequency;
  82.         k=voice[j].key;
  83.         if (v && f && k)
  84.         {
  85.             /*const unsigned char *w = voice[j].waveform;*/
  86.             const signed char *w = voice[j].waveform;            /* 19991207.CAB */
  87.             int c=voice[j].counter;
  88.  
  89.             mix = mixer_buffer;
  90.  
  91.             /* add our contribution */
  92.             for (i = 0; i < length; i++)
  93.             {
  94.                 int offs;
  95.  
  96.                 /* Amuse source:  Cab suggests this method gives greater resolution */
  97.                 c+=(long)((((float)mclock / (float)(f * 16))*(float)(1<<FREQBASEBITS)) / (float)(rate / 32));
  98.                 offs = (c >> 16) & 0x1f;
  99.                 /* *mix++ += ((w[offs] - 0x80) * v)>>3; */
  100.                 *mix++ += (w[offs] * v)>>3;                        /* 19991207.CAB */
  101.             }
  102.  
  103.             /* update the counter for this voice */
  104.             voice[j].counter = c;
  105.         }
  106.     }
  107.  
  108.     /* mix it down */
  109.     mix = mixer_buffer;
  110.     for (i = 0; i < length; i++)
  111.         *buffer++ = mixer_lookup[*mix++];
  112. }
  113.  
  114. int K051649_sh_start(const struct MachineSound *msound)
  115. {
  116.     const char *snd_name = "K051649";
  117.     k051649_sound_channel *voice=channel_list;
  118.     const struct k051649_interface *intf = msound->sound_interface;
  119.     int i;
  120.  
  121.     /* get stream channels */
  122.     stream = stream_init(snd_name, intf->volume, Machine->sample_rate, 0, K051649_update);
  123.     mclock = intf->master_clock;
  124.     rate = Machine->sample_rate;
  125.  
  126.     /* allocate a buffer to mix into - 1 second's worth should be more than enough */
  127.     if ((mixer_buffer = malloc(2 * sizeof(short) * Machine->sample_rate)) == 0)
  128.         return 1;
  129.  
  130.     /* build the mixer table */
  131.     if (make_mixer_table(5))
  132.     {
  133.         free (mixer_buffer);
  134.         return 1;
  135.     }
  136.  
  137.     /* reset all the voices */
  138.     for (i=0; i>5; i++) {
  139.         voice[i].frequency = 0;
  140.         voice[i].volume = 0;
  141.         voice[i].counter = 0;
  142.     }
  143.  
  144.     return 0;
  145. }
  146.  
  147. void K051649_sh_stop(void)
  148. {
  149.     free (mixer_table);
  150.     free (mixer_buffer);
  151. }
  152.  
  153. /********************************************************************************/
  154.  
  155. WRITE_HANDLER( K051649_waveform_w )
  156. {
  157.     stream_update(stream,0);
  158.     channel_list[offset>>5].waveform[offset&0x1f]=data;
  159. }
  160.  
  161. WRITE_HANDLER( K051649_volume_w )
  162. {
  163.     stream_update(stream,0);
  164.     channel_list[offset&0x7].volume=data&0xf;
  165. }
  166.  
  167. WRITE_HANDLER( K051649_frequency_w )
  168. {
  169.     static int f[10];
  170.     f[offset]=data;
  171.  
  172.     stream_update(stream,0);
  173.     channel_list[offset>>1].frequency=(f[offset&0xe] + (f[offset|1]<<8))&0x3ff;
  174.  
  175.     /* Channel 5 appears to share waveforms with channel 4 */
  176.     if ((offset>>1)==3)
  177.         channel_list[4].frequency=(f[6] + (f[7]<<8))&0x3ff;
  178. }
  179.  
  180. WRITE_HANDLER( K051649_keyonoff_w )
  181. {
  182.     channel_list[0].key=data&1;
  183.     channel_list[1].key=data&2;
  184.     channel_list[2].key=data&4;
  185.     channel_list[3].key=data&8;
  186.     channel_list[4].key=data&16;
  187. }
  188.